//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see http://www.gnu.org/licenses/.
// 

package inet.applications.stemNetStimulus;

import inet.applications.udpapp.UDPBasicApp;
import inet.applications.IUDPApp;

simple StemNetStimulusBrain like IUDPApp
{
    parameters:
        ////// FROM UDP App
        int localPort = default(-1);  // local port (-1: use ephemeral port)
        string destAddresses = default(""); // list of IP addresses, separated by spaces ("": don't send)
        int destPort;
        volatile int messageLength @unit(B); // length of messages to generate, in bytes
        double startTime @unit(s) = default(this.sendInterval); // application start time (start of the first packet)
        double stopTime @unit(s) = default(-1s);  // time of finishing sending, -1s means forever
        volatile double sendInterval @unit(s); // should usually be a random value, e.g. exponential(1)
        int timeToLive = default(-1); // if not -1, set the TTL (IPv4) or Hop Limit (IPv6) field of sent packets to this value
        int typeOfService = default(-1); // if not -1, set the ToS (IPv4) or Traffic Class (IPv6) field of sent packets to this value
        string multicastInterface = default("");  // if not empty, set the multicast output interface option on the socket (interface name expected)
        bool receiveBroadcast = default(false); // if true, makes the socket receive broadcast packets
        bool joinLocalMulticastGroups = default(false); // if true, makes the socket receive packets from all multicast groups set on local interfaces
        ///////////
        
        double stimulusBroadcastStepTime @unit(s) = default(5s);
        double gatewayBroadcastStepTime @unit(s) = default(30s);
        int maxStimulusStep = default(2);
        int localPortStim = default(-1);  // local port (-1: use ephemeral port)
        int destPortStim;
        
        double decisionStepTime @unit(s) = default(5s);
        
        double trafficStepTime @unit(s) = default(1s); 
        volatile int messageStepLength @unit(B) = default(1024B); // length of messages to generate, in bytes
        
        int responseFunctionExponent = default(3);    
        int totalResponseFunctionExponent = default(1);
        
        double maxForwardDelay @unit(s) = default(0.5s);  	// max delay before forwarding messages
        double timeElectionPhase @unit(s) = default(3s);  	// election phase duration (T_{e} parameter)
        
        // variable definitions for the status metric of a gateway
        double alpha_ = default(0.5);
        double beta_ = default(0.5);
        
        // variable definitions for the threshold metric
        double gamma_ = default(0.3);
        double delta_ = default(0.3);
        double eta_ = default(0.4);
        
        string electionType @enum("Single","Multiple") = default("Single");  // election type
        
        double gatewayProbability = default(0.8);		// probability to stay as gateway or leave the role
        
        double module3GProbability = default(0.33);		// probability to have a 3Gmodule
        
        // function activation
        bool sendStimulus = default(true);
        bool sendGatewayMsg = default(true);
        bool sendPeriodicGatewayMsg = default(true);
        
        // protocols
        string protocolType @enum("stemnet","bestGW", "probabilistic", "distance") = default("stemnet");  // protocol type
        bool becomeGWifAlone = default(true);
        double protocolTimer @unit(s) = default(60s);
        bool stimulusOnRouting = default(true);
        double probabilisticValue = default(0.5);
        int distanceToGW = default(1);
        
        @display("i=block/app");
        @signal[sentPk](type=cPacket);
        @signal[rcvdPk](type=cPacket);
        @statistic[rcvdPk](title="packets received"; source=rcvdPk; record=count,"sum(packetBytes)","vector(packetBytes)"; interpolationmode=none);
        @statistic[sentPk](title="packets sent"; source=sentPk; record=count,"sum(packetBytes)","vector(packetBytes)"; interpolationmode=none);
        @statistic[rcvdPkLifetime](title="received packet lifetime"; source="messageAge(rcvdPk)"; unit=s; record=stats,vector; interpolationmode=none);
        
        
    gates:
        
        // connect the KnowledgeRepository
        input dbIn;
        output dbOut;
        
        // connect the WiFi Nic
        input udpIn @labels(UDPControlInfo/up);
        output udpOut @labels(UDPControlInfo/down);
        
        // connect the 3G dummy module
        input dummy3GIn;
        output dummy3GOut;
}